from loguru import logger
import threading
from flask import Flask, request, jsonify, Response
import requests
import socket
import errno
import os
import re   #正则

_default = logger
app = Flask(__name__)

client_socket = None
httplock = threading.Semaphore(1)
tts_ip = None
tts_port = 30000

@app.route('/reg')
def registe_http():
    global tts_ip
    tts_ip = request.remote_addr
    print('tts的http地址注册上了 ', tts_ip)

@app.route('/token')
def get_token():
    return "True", 200

@app.route('/tts', methods=['POST'])
def convert_text_to_speech():
    text = request.json.get('text')
    if not text or text == "":
        return jsonify({'error': 'No text provided'}), 400
    if does_not_contain_chinese(text):
        return jsonify({'error': 'Only Chinese supurt'}), 400
    # 发送文本到TTS处理端
    print(f"收到了 {text}")
    print(client_socket)
    audio = send_text_to_tts(text)
    if audio is not None:
        #return res, 200
        return audio, 200
    else:
        return jsonify({'error': 'TTS busy'}), 409
    #return jsonify({'audio':"asdfasdf"}), 200

# 判断字符串不包含汉字
def does_not_contain_chinese(s):
    # 正则表达式，匹配任何汉字字符
    chinese_pattern = re.compile(r'[\u4e00-\u9fff]+')
    # 如果字符串中不包含汉字字符，则返回True，否则返回False
    return not chinese_pattern.search(s)

# @app.route('/tts', methods=['POST'])
# def convert_text_to_speech_http():
#     '''
#     tts请求，http处理版
#     '''
#     text = request.json.get('text')
#     if not text:
#         return jsonify({'error':'No text provided'}), 400
#     # 发送文本到TTS处理端
#     print(f"收到了 {text}")
#
#     stream_audio_url = f'http://{tts_ip}:{tts_port}/tts'
#     resp = requests.post(stream_audio_url, data={'text': text}, stream=False)
#     print('返回', resp)
#     def generate():
#         for chunk in resp.iter_content(chunk_size=4096):
#             yield chunk
#
#     #return Response(generate(), mimetype='audio/wav')
#     return jsonify({'ok': 'TTS ok'}), 200

def send_text_to_tts(text):
    global client_socket
    if httplock.acquire(blocking=False):
        if client_socket is None:
            return None
        print("not none not return")
        send(client_socket, text)
        #return text.encode()
        try:
            # 接收音频流
            lengthBytes = client_socket.recv(4)
            dataLength = int.from_bytes(lengthBytes, byteorder='little')
            print(f"recv 1  {dataLength}")
            audio_data = b''
            # print("recv 2")
            # lengthBytes2 = client_socket.recv(4)
            # dataLength2 = int.from_bytes(lengthBytes2, byteorder='little')
            # phoneme_data = b''

            while len(audio_data) < dataLength:
                print("recv 3")
                packet = client_socket.recv(dataLength - len(audio_data))
                print("recv 4")
                if not packet:
                    break
                audio_data += packet
            print(f"tcp recv audio len {len(audio_data)}")

            # while len(phoneme_data) < dataLength2:
            #     print("recv 5")
            #     packet = client_socket.recv(dataLength2 - len(phoneme_data))
            #     print("recv 6")
            #     if not packet:
            #         break
            #     phoneme_data += packet
            # print(f"tcp recv phoneme len {len(phoneme_data)}")

            # print(f"tcp recv {audio_data.decode()}")
            # tts_socket.close()
            httplock.release()
            return audio_data
        except socket.error as e:
            httplock.release()
            return None
    else:
        return None


def runapp():
    global app
    app.run(host='0.0.0.0', port=30100)

tcptag = False
def send(sock, msg):
    #global client_socket
    print("fa")
    if sock is not None:
        print("sock is not none")
        tmp = msg.encode()
        dataLength = len(tmp)
        # 发送包长信息
        lengthBytes = dataLength.to_bytes(4, byteorder='little')
        print("sock is not none1")
        try:
            sock.sendall(lengthBytes)
            # 发送数据
            sock.sendall(tmp)
            print("sock is not none2")
        except socket.error as e:
            print(f"sock error1 {e.errno}")
            print(f"sock error2 {str(e)}")
            print(f"sock error3 {e}")
    else:
        print("sock is none")

def recvthd(client_socket, addr):
    global tcptag
    count = 50
    while tcptag:
        count -= 1
        if count < 0:
            count = 50
            send(client_socket, "python send ")
        # 接收包长信息
        try:
            lengthBytes = client_socket.recv(4)
            dataLength = int.from_bytes(lengthBytes, byteorder='little')
            data = b''
            while len(data) < dataLength:
                packet = client_socket.recv(dataLength - len(data))
                if not packet:
                    break
                data += packet
            print("Received:", data.decode())

        except socket.error as e:
            if os.name == 'posix' and e.errno == errno.EWOULDBLOCK:
                time.sleep(0.1)
                continue
            elif os.name == 'nt' and e.errno == errno.WSAEWOULDBLOCK:
                time.sleep(0.1)
                continue
            break

def tmpcheckloop():
    import time
    while True:
        time.sleep(5)
        if client_socket is None:
            continue
        try:
            alive = client_socket.getsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE)
            print(f"Socket keep-alive: {'ON' if alive else 'OFF'}")
        except socket.error as e:
            print(f"Socket error: {e}")
def tokeeptcp():
    import time
    while True:
        time.sleep(20)
        if client_socket is None:
            continue
        try:
            send(client_socket, '太撒吊了')
            print(f"send ping")
        except socket.error as e:
            print(f"Socket error: {e}")

if __name__ == "__main__":
    import time
    t = threading.Thread(target=runapp)
    t.daemon = True
    t.start()
    # tt = threading.Thread(target=tmpcheckloop)
    # tt.daemon = True
    # tt.start()
    tt = threading.Thread(target=tokeeptcp)
    tt.daemon = True
    tt.start()
    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server.bind(('0.0.0.0', 30099))
    server.listen(1)
    try:
        while True:
            print("主进程运行中")
            client_socket, addr = server.accept()
            #client_socket.setsockopt(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1)
            #client_socket.setblocking(False)
            tcptag = True
            #client_thread = threading.Thread(target=recvthd, args=(client_socket, addr))
            #client_thread.start()

            print(f"client connect {addr}")
            #time.sleep(1)
    except KeyboardInterrupt:
        print("stop")
        tcptag = False
        if client_socket is not None:
            client_socket.close()
        server.close()

